#include "MBPlane.h"

const MBuint X = 0u;
const MBuint Y = 1u;
const MBuint Z = 2u;

/**
  * Constructs a new MBPlane object with the given arguments
  *
  * @param normal normal vector of the plane
  * @param point any point that is lying on the plane
  */
MBPlane::MBPlane( const MBVec3 &normal, const MBVec3 &point ) : 
	mNormal( normal ),
	mPoint( point )
{
	mD = MBVec3::Dot( -normal, point );
}

/**
  * Returns the distance between this plane and the given point
  *
  * @param point point in 3D space for which the distance to the plane is calculated
  * @return distance between this plane and the given point
  */
double MBPlane::GetDistanceToPoint( const MBVec3 &point ) const
{
	return MBVec3::Dot( mNormal, point ) + mD;
}

/**
  * Tests whether the positive vertex of the delivered axis aligned box (with respect to the plane)
  * is lying outside (on the backside) of the plane or not
  *
  * @param boxMin Minimum point of the axis aligned box
  * @param boxMax Maximum point of the axis aligned box
  * @return Boolean value indicating whether the positive vertex of the delivered axis aligned box
  *			(with respect to the plane) is lying outside (on the backside) of the plane or not
  */
bool MBPlane::IsPositiveVertexOfAxisAlignedBoxOutside( const MBVec3 &boxMin, const MBVec3 &boxMax ) const
{
	MBVec3 p = boxMin;
	if (mNormal[X] >= 0)
		p[X] = boxMax[X];
	if (mNormal[Y] >= 0)
		p[Y] = boxMax[Y];
	if (mNormal[Z] >= 0)
		p[Z] = boxMax[Z];

	if (MBVec3::Dot( mNormal, p ) + mD < 0.0)
		return true;

	return false;
}

/**
  * Sets the normal vector and one point lying on the plane
  *
  * @param normal normal vector
  * @param point any point lying on the plane
  */
void MBPlane::SetNormalAndPoint( const MBVec3 &normal, const MBVec3 &point )
{
	mNormal = normal;
	mPoint = point;

	mD = MBVec3::Dot( -normal, point );
}